package com.curator.component;


import cn.hutool.core.compress.ZipReader;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.core.util.StrUtil;
import com.curator.install.InstallService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.StandardCopyOption;

/**
 * 组件安装 策略
 *
 * @author Jun
 * @date 2024/12/04
 */
public abstract class AbstractComponentInstall {

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractComponentInstall.class);


    /**
     * 组件名称
     *
     * @return {@link String}
     */
    abstract String componentName();

    /**
     * 组件安装
     *
     * @param inputStream 输入流
     * @param runScript 运行脚本
     */
    public void componentInstall(InputStream inputStream, boolean runScript) {
        try {
            LOGGER.info("{} 安装开始", componentName());
            File destFile = new File(getFilePath(componentName(), ".zip"));
            FileUtil.copyFile(inputStream, destFile, StandardCopyOption.REPLACE_EXISTING);
            inputStream.close();
            unZip(destFile);
            LOGGER.info("{} 压缩文件解压成功", componentName());
            FileUtil.del(destFile);
            LOGGER.info("{} 压缩文件删除成功", componentName());
            // 注册为服务
            if (runScript) {
                scriptInstall();
            }
        } catch (Exception e) {
            LOGGER.error("{} 组件释放出现异常: {}", componentName(), ExceptionUtil.stacktraceToString(e));
        }
    }

    public void scriptInstall() {
        try {
            Process execProcess = RuntimeUtil.exec(getFilePath(componentName(), "\\install.bat"));
            int exitCode = execProcess.waitFor();
            // 判断脚本是否成功执行
            if (exitCode == 0) {
                LOGGER.info("{} 安装脚本执行成功", componentName());
            } else {
                LOGGER.error("{} 安装脚本执行失败，{}", componentName(), RuntimeUtil.getErrorResult(execProcess, StandardCharsets.UTF_8));
            }
        } catch (Exception e) {
            LOGGER.error("{} 安装脚本出现异常: {}", componentName(), ExceptionUtil.stacktraceToString(e));
        }
    }

    public String getFilePath(String param1, String param2) {
        String template = InstallService.INSTALL_PATH + "\\\\{}{}";
        return StrUtil.format(template, param1, param2);
    }

    /**
     * 解压文件
     *
     * @param destFile dest文件
     */
    public void unZip(File destFile) {
        try (ZipReader zipReader = new ZipReader(destFile, StandardCharsets.UTF_8);) {
            // -1表示不检查ZipBomb
            zipReader.setMaxSizeDiff(-1);
            zipReader.readTo(new File(InstallService.INSTALL_PATH + "\\" + componentName()));
        } catch (Exception e) {
            LOGGER.error("{} 解压出现异常: {}", componentName(), ExceptionUtil.stacktraceToString(e));
        }
    }
}
